{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "8e3a90be-5710-4243-b65f-dbe928df97dc",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "MNIST数据形状: (70000, 784)\n",
      "标签形状: (70000,)\n"
     ]
    }
   ],
   "source": [
    "from sklearn.datasets import fetch_openml\n",
    "import numpy as np\n",
    "\n",
    "# 读取 MNIST 数据集\n",
    "mnist = fetch_openml('mnist_784')\n",
    "\n",
    "# 获取数据和标签\n",
    "X = mnist.data.values\n",
    "y = mnist.target.astype(int).values\n",
    "\n",
    "# 打印数据的形状\n",
    "print(f\"MNIST数据形状: {X.shape}\")\n",
    "print(f\"标签形状: {y.shape}\")\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "48418927-b1e0-476e-b1b5-0effa18fb66c",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "   time  rssi_1  rssi_2  rssi_3   action\n",
      "0     1     -96     -79     -60  walking\n",
      "1     2     -81     -99     -53  walking\n",
      "2     3     -69     -83     -54  walking\n",
      "3     4     -73     -61     -72  running\n",
      "4     5     -60     -85     -66  sitting\n"
     ]
    }
   ],
   "source": [
    "import pandas as pd\n",
    "import numpy as np\n",
    "\n",
    "# 创建一个虚拟的Wi-Fi数据集\n",
    "# 假设包含时间、Wi-Fi信号强度 (RSSI) 和动作类别\n",
    "data = {\n",
    "    'time': np.arange(1, 101),  # 时间戳\n",
    "    'rssi_1': np.random.randint(-100, -50, 100),  # Wi-Fi信号强度1\n",
    "    'rssi_2': np.random.randint(-100, -50, 100),  # Wi-Fi信号强度2\n",
    "    'rssi_3': np.random.randint(-100, -50, 100),  # Wi-Fi信号强度3\n",
    "    'action': np.random.choice(['walking', 'running', 'sitting'], 100)  # 动作标签\n",
    "}\n",
    "\n",
    "# 创建 DataFrame\n",
    "wifi_data = pd.DataFrame(data)\n",
    "\n",
    "# 查看数据集\n",
    "print(wifi_data.head())\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "cf345f9b-26d2-4368-a31c-205ca5c211ae",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "   time  rssi_1  rssi_2  rssi_3   action  action_encoded\n",
      "0     1     -96     -79     -60  walking               2\n",
      "1     2     -81     -99     -53  walking               2\n",
      "2     3     -69     -83     -54  walking               2\n",
      "3     4     -73     -61     -72  running               0\n",
      "4     5     -60     -85     -66  sitting               1\n"
     ]
    }
   ],
   "source": [
    "from sklearn.preprocessing import LabelEncoder\n",
    "\n",
    "# 编码动作标签\n",
    "label_encoder = LabelEncoder()\n",
    "wifi_data['action_encoded'] = label_encoder.fit_transform(wifi_data['action'])\n",
    "\n",
    "# 显示处理后的数据\n",
    "print(wifi_data.head())\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "c74b4358-0839-4902-af7c-b4748d9c2721",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Downloading http://yann.lecun.com/exdb/mnist/train-images-idx3-ubyte.gz\n",
      "Failed to download (trying next):\n",
      "HTTP Error 403: Forbidden\n",
      "\n",
      "Downloading https://ossci-datasets.s3.amazonaws.com/mnist/train-images-idx3-ubyte.gz\n",
      "Downloading https://ossci-datasets.s3.amazonaws.com/mnist/train-images-idx3-ubyte.gz to ./data\\MNIST\\raw\\train-images-idx3-ubyte.gz\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "100.0%\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Extracting ./data\\MNIST\\raw\\train-images-idx3-ubyte.gz to ./data\\MNIST\\raw\n",
      "\n",
      "Downloading http://yann.lecun.com/exdb/mnist/train-labels-idx1-ubyte.gz\n",
      "Failed to download (trying next):\n",
      "HTTP Error 403: Forbidden\n",
      "\n",
      "Downloading https://ossci-datasets.s3.amazonaws.com/mnist/train-labels-idx1-ubyte.gz\n",
      "Downloading https://ossci-datasets.s3.amazonaws.com/mnist/train-labels-idx1-ubyte.gz to ./data\\MNIST\\raw\\train-labels-idx1-ubyte.gz\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "100.0%\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Extracting ./data\\MNIST\\raw\\train-labels-idx1-ubyte.gz to ./data\\MNIST\\raw\n",
      "\n",
      "Downloading http://yann.lecun.com/exdb/mnist/t10k-images-idx3-ubyte.gz\n",
      "Failed to download (trying next):\n",
      "HTTP Error 403: Forbidden\n",
      "\n",
      "Downloading https://ossci-datasets.s3.amazonaws.com/mnist/t10k-images-idx3-ubyte.gz\n",
      "Downloading https://ossci-datasets.s3.amazonaws.com/mnist/t10k-images-idx3-ubyte.gz to ./data\\MNIST\\raw\\t10k-images-idx3-ubyte.gz\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "100.0%\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Extracting ./data\\MNIST\\raw\\t10k-images-idx3-ubyte.gz to ./data\\MNIST\\raw\n",
      "\n",
      "Downloading http://yann.lecun.com/exdb/mnist/t10k-labels-idx1-ubyte.gz\n",
      "Failed to download (trying next):\n",
      "HTTP Error 403: Forbidden\n",
      "\n",
      "Downloading https://ossci-datasets.s3.amazonaws.com/mnist/t10k-labels-idx1-ubyte.gz\n",
      "Downloading https://ossci-datasets.s3.amazonaws.com/mnist/t10k-labels-idx1-ubyte.gz to ./data\\MNIST\\raw\\t10k-labels-idx1-ubyte.gz\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "100.0%"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Extracting ./data\\MNIST\\raw\\t10k-labels-idx1-ubyte.gz to ./data\\MNIST\\raw\n",
      "\n",
      "Batch of images: torch.Size([64, 1, 28, 28])\n",
      "Batch of labels: torch.Size([64])\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\n"
     ]
    }
   ],
   "source": [
    "import torch\n",
    "from torchvision import datasets, transforms\n",
    "from torch.utils.data import DataLoader\n",
    "\n",
    "# Define the transformations (you can add more transformations if needed)\n",
    "transform = transforms.Compose([transforms.ToTensor(), transforms.Normalize((0.5,), (0.5,))])\n",
    "\n",
    "# Download and load the MNIST training dataset\n",
    "trainset = datasets.MNIST(root='./data', train=True, download=True, transform=transform)\n",
    "\n",
    "# Download and load the MNIST test dataset\n",
    "testset = datasets.MNIST(root='./data', train=False, download=True, transform=transform)\n",
    "\n",
    "# Create DataLoader for the training set\n",
    "trainloader = DataLoader(trainset, batch_size=64, shuffle=True)\n",
    "\n",
    "# Create DataLoader for the test set\n",
    "testloader = DataLoader(testset, batch_size=64, shuffle=False)\n",
    "\n",
    "# Check the shape of the data by iterating through the trainloader\n",
    "for images, labels in trainloader:\n",
    "    print(f\"Batch of images: {images.size()}\")  # Example: torch.Size([64, 1, 28, 28])\n",
    "    print(f\"Batch of labels: {labels.size()}\")  # Example: torch.Size([64])\n",
    "    break  # Only print the first batch\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "b745fd2b-d99a-4886-85ef-0892c986565c",
   "metadata": {},
   "outputs": [],
   "source": [
    "import torch.nn as nn\n",
    "import torch.optim as optim\n",
    "\n",
    "class FNN(nn.Module):\n",
    "    def __init__(self, input_size, hidden_layers, hidden_units, output_size=10):\n",
    "        super(FNN, self).__init__()\n",
    "        \n",
    "        # 定义层\n",
    "        layers = []\n",
    "        prev_units = input_size\n",
    "        for _ in range(hidden_layers):\n",
    "            layers.append(nn.Linear(prev_units, hidden_units))\n",
    "            layers.append(nn.ReLU())\n",
    "            prev_units = hidden_units\n",
    "        layers.append(nn.Linear(prev_units, output_size))\n",
    "        \n",
    "        self.model = nn.Sequential(*layers)\n",
    "        \n",
    "    def forward(self, x):\n",
    "        return self.model(x)\n",
    "\n",
    "# 定义网络结构：MNIST图像为28x28 = 784维输入\n",
    "input_size = 784\n",
    "hidden_layers = 2  # 可自定义\n",
    "hidden_units = 128  # 可自定义\n",
    "output_size = 10  # MNIST有10个类别\n",
    "\n",
    "# 初始化模型\n",
    "model = FNN(input_size, hidden_layers, hidden_units, output_size)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "cdbfded8-2c4f-48a3-9063-a0ba336a688e",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch [1/5], Loss: 0.3699\n",
      "Epoch [2/5], Loss: 0.1700\n",
      "Epoch [3/5], Loss: 0.1253\n",
      "Epoch [4/5], Loss: 0.0987\n",
      "Epoch [5/5], Loss: 0.0839\n"
     ]
    }
   ],
   "source": [
    "# 定义损失函数和优化器\n",
    "criterion = nn.CrossEntropyLoss()\n",
    "optimizer = optim.Adam(model.parameters(), lr=0.001)\n",
    "\n",
    "# 训练函数\n",
    "def train(model, trainloader, criterion, optimizer, epochs=5):\n",
    "    model.train()\n",
    "    train_losses = []\n",
    "    \n",
    "    for epoch in range(epochs):\n",
    "        running_loss = 0.0\n",
    "        for inputs, labels in trainloader:\n",
    "            inputs = inputs.view(inputs.size(0), -1)  # Flatten the inputs (28x28 -> 784)\n",
    "            \n",
    "            optimizer.zero_grad()  # 清空梯度\n",
    "            outputs = model(inputs)\n",
    "            loss = criterion(outputs, labels)\n",
    "            loss.backward()  # 反向传播\n",
    "            optimizer.step()  # 优化步骤\n",
    "            \n",
    "            running_loss += loss.item()\n",
    "        \n",
    "        epoch_loss = running_loss / len(trainloader)\n",
    "        train_losses.append(epoch_loss)\n",
    "        print(f\"Epoch [{epoch+1}/{epochs}], Loss: {epoch_loss:.4f}\")\n",
    "    \n",
    "    return train_losses\n",
    "\n",
    "# 训练模型\n",
    "train_losses = train(model, trainloader, criterion, optimizer, epochs=5)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b063c19a-81fe-42b7-8ff8-b6fcf1cd6389",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "551ddecf-cca5-447b-ba46-7f7521c64a2b",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Test Accuracy: 17.10%\n"
     ]
    },
    {
     "data": {
      "image/png": "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",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "\n",
    "# 测试函数\n",
    "def test(model, testloader):\n",
    "    model.eval()  # 切换到评估模式\n",
    "    correct = 0\n",
    "    total = 0\n",
    "    with torch.no_grad():  # 不计算梯度\n",
    "        for inputs, labels in testloader:\n",
    "            inputs = inputs.view(inputs.size(0), -1)\n",
    "            outputs = model(inputs)\n",
    "            _, predicted = torch.max(outputs, 1)\n",
    "            total += labels.size(0)\n",
    "            correct += (predicted == labels).sum().item()\n",
    "    \n",
    "    accuracy = 100 * correct / total\n",
    "    print(f\"Test Accuracy: {accuracy:.2f}%\")\n",
    "    return accuracy\n",
    "\n",
    "# 测试模型\n",
    "test_accuracy = test(model, testloader)\n",
    "\n",
    "# 绘制学习曲线\n",
    "plt.plot(range(1, 6), train_losses, label='Training Loss')\n",
    "plt.xlabel('Epoch')\n",
    "plt.ylabel('Loss')\n",
    "plt.title('Training Loss over Epochs')\n",
    "plt.legend()\n",
    "plt.show()\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "0b402087-135d-45e5-a0d7-fd3e7431af2a",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.14"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
